package initialization

import (
	"gitee.com/danlansky/go-library/logs"
	"github.com/spf13/viper"
)

// InitConfigBuilder 初始化配置加载 其中 base 和 metric 必须加载
// base 配置文件格式 其中包含了程序基本信息和日志配置
// [app]
//     name = "app"
//     desc = "app server"
//     env = "test"
//     [app.server]
//         port = ":8080"
//     [app.log]
//         root_path = "./"
//         local_ip = "127.0.0.1"
type initConfigBuilder struct {
	base     *appConfig
	database bool
	redis    bool
	mongoDB  bool
	kafka    bool
}

// NewConfigBuilder 构造文件
// env 环境和 metric 打点必填 用来初始化必要信息
// 构造函数 加载必要的应用基础内容和日志配置
// module 参数用来区分不同的模块对应不同的配置, module配置放在config目录下
// 	例如: 一个模块为test-module
// 	则: 启动命令为 app --module=test-module --config=prod
// 	则: 该模块的配置文件路径为 config/test-module/config-test.toml
func NewConfigBuilder(env string, module string) *initConfigBuilder {
	builder := &initConfigBuilder{}
	builder.base = initConfig(env, module)

	initLog(builder.base)
	return builder
}

func NewConfigBuilderWithIP(env string, module string, ip string) *initConfigBuilder {
	builder := &initConfigBuilder{}
	builder.base = initConfig(env, module)
	builder.base.Log.LocalIP = ip
	initLog(builder.base)
	return builder
}

func NewConfigBuildWithPath(path string, modPath string) *initConfigBuilder {
	builder := &initConfigBuilder{}

	viper.SetConfigFile(path)
	if err := viper.MergeInConfig(); err != nil {
		panic(err)
	}

	if modPath != "" {
		viper.SetConfigFile(modPath)
		if err := viper.MergeInConfig(); err != nil {
			panic(err)
		}
	}

	a := &appConfig{}
	_ = viper.UnmarshalKey(baseConfigTag, a)
	if a.Name == "" || a.Desc == "" || a.Env == "" || a.Server.Port == "" {
		panic("app config error")
	}

	builder.base = a

	initLog(builder.base)
	return builder
}

func (b *initConfigBuilder) GetConfigPath() string {
	return configPath
}

// WithDatabase 数据库配置
// 使用的 repository/mysqldb/mysql.go InitMysqlDB 读写分离方式加载
// 配置文件格式:
// [mysql]
//     [mysql.open_push]
//         name = "database connection name"
//         write = "write host"
//         write_username = "write username"
//         write_password = "write password"
//         read = "read host"
//         read_username = "read username"
//         read_password = "read password"
//         database = "database name"
//         max_pool_size = pool size default 10
//         max_idle = max idle defaule 5
//         idle_timeout = idle timeout default 6s
//         connect_timeout = connect timeout default 1s
//         do_with_timeout = do with timeout default  1s
// 配置文件中需要配置默认数据库连接
// [database]
//     [database.default]
//         name = "harmony_push"
// !!! => timeout 时间的单位 纳秒，按照 golang 的时间类型配置 time.Duration
func (c *initConfigBuilder) WithDatabase() *initConfigBuilder {
	c.database = true
	return c
}

// WithRedis redis配置
// 配置文件格式:
// [redis]
//     [redis.harmony_push]
//         name = "harmony_push"
//         type = "redis"
//         addr = ["10.136.27.189:6379"]
//         max_pool_size = 10
//         idle_timeout = timeout default 6s
//         connect_timeout = timeout default 1s
//         do_with_timeout = timeout default 1s
func (c *initConfigBuilder) WithRedis() *initConfigBuilder {
	c.redis = true
	return c
}

// WithMongoDB mongo配置
// 配置文件格式：
// [mongo]
// 	[mongo.default]
// 		name = "mongo config name"
// 		type = "mongo cinfig type"
// 		addr = "mongo host"
// 		read_preference_mode = ""
// 		max_pool_size = "max connect"
// 		connect_timeout = "timeout default 2s"
// 		do_with_timeout = "timeout default 2s"
func (c *initConfigBuilder) WithMongoDB() *initConfigBuilder {
	c.mongoDB = true
	return c
}

// WithKafka 配置
// [kafka_producer]
//    [kafka_producer.taotaoke]
//        name = "taotaoke"
//        hosts = ["192.168.40.88:9092"]
//        topic = "taoke_caiji"
//        return_success = true   #同步生产时，ReturnSuccess必须指定为true
//        return_error = true     #同步生产时，ReturnError默认为true
//        required_acks = 1 #ack确认机制，默认是1，即WaitForLocal
//        timeout = 1000 #socket的超时时间，ms毫秒
//        max_retry = 3 #最大重试次数
//
//[kafka_consumer]
//    [kafka_consumer.taotaoke]
//        name = "taotaoke"
//        hosts = ["192.168.40.88:9092"]
//        topic = "taoke_caiji"
//        group_id = "group_taoke_caiji_test"
//        offset=-1 #Offset 值只能为-1或-2，-1代表无偏移量时从最新位置开始消费，-2代表无偏移量时从最老的位置开始消费
//        auto_commit = false   #AutoCommit 默认自动提交
//        return_error = true    #同步生产时，ReturnError默认为true
//        max_retry = 3 #最大重试次数

func (c *initConfigBuilder) WithKafka() *initConfigBuilder {
	c.kafka = true
	return c
}

// Init 根据 With 方法进行初始化
func (c *initConfigBuilder) Init() {

	if c.database {
		initDatabase()
		logs.AccessLog("Database config init success!")
	}

	if c.redis {
		initRedis()
		logs.AccessLog("Redis config init success!")
	}

	if c.mongoDB {
		initMongo()
		logs.AccessLog("MongoDB config init success!")
	}

	//if c.kafka {
	//	initKafka()
	//	logs.AccessLog("Kafka config init success!")
	//}

	logs.AccessLog("Config init success!")
}
